﻿Imports System.Web
Imports System.Text

Namespace DotNetNuke.Modules.ActiveForums.Handlers
    Public Class HandlerBase
        Implements System.Web.IHttpHandler
        Friend Enum OutputCodes
            Success
            UnsupportedRequest
            AuthenticationFailed
            Exception
            NoResults
            AccessDenied
        End Enum
        Private _userProfile As User
        Private _params As Hashtable
        Private _isValid As Boolean = False
        Private _gid As Integer = -1
        Private _groupid As Integer = -1
        Private _upid As Integer = -1
        Private _ps As DotNetNuke.Entities.Portals.PortalSettings
        Private _mainSettings As SettingsInfo
        Public Property AdminRequired As Boolean = False
        Private _pid As Integer = -1
        Private _mid As Integer = -1
        Public Property UserId() As Integer = -1
        Public ReadOnly Property PortalId() As Integer
            Get
                If Not HttpContext.Current.Request.QueryString("PortalId") Is Nothing AndAlso IsNumeric(HttpContext.Current.Request.QueryString("PortalId")) Then
                    Return Integer.Parse(HttpContext.Current.Request.QueryString("PortalId"))
                Else
                    Return _pid
                End If
            End Get
        End Property
        Public ReadOnly Property ModuleId() As Integer
            Get
                If Not HttpContext.Current.Request.QueryString("ModuleId") Is Nothing AndAlso IsNumeric(HttpContext.Current.Request.QueryString("ModuleId")) Then
                    Return Integer.Parse(HttpContext.Current.Request.QueryString("ModuleId"))
                Else
                    Return _mid
                End If
            End Get
        End Property
        Public ReadOnly Property TabId() As Integer
            Get
                If Not HttpContext.Current.Request.QueryString("TabId") Is Nothing AndAlso IsNumeric(HttpContext.Current.Request.QueryString("TabId")) Then
                    Return Integer.Parse(HttpContext.Current.Request.QueryString("TabId"))
                Else
                    Return -1
                End If
            End Get
        End Property
        Public ReadOnly Property IsDebug() As Boolean
            Get
                If Not HttpContext.Current.Request.QueryString("amdebug") Is Nothing Then
                    Return Boolean.Parse(HttpContext.Current.Request.QueryString("amdebug"))
                Else
                    Return False
                End If
            End Get
        End Property
        Public ReadOnly Property MainSettings() As SettingsInfo
            Get
                Return _mainSettings
            End Get
        End Property
        Public ReadOnly Property IsValid() As Boolean
            Get
                Return _isValid
            End Get
        End Property
        Public ReadOnly Property PS() As DotNetNuke.Entities.Portals.PortalSettings
            Get
                Return _ps
            End Get
        End Property
        Public ReadOnly Property RequestOption() As Integer
            Get
                If Not HttpContext.Current.Request.QueryString("opt") Is Nothing AndAlso IsNumeric(HttpContext.Current.Request.QueryString("opt")) Then
                    Return Integer.Parse(HttpContext.Current.Request.QueryString("opt"))
                Else
                    Return -1
                End If
            End Get
        End Property
        Public ReadOnly Property Params() As Hashtable
            Get
                Return _params
            End Get
        End Property

        Public ReadOnly Property UPID() As Integer
            Get
                Return _upid
            End Get
        End Property

        Public Property IsAuthenticated() As Boolean = False
        Public Property Username() As String = String.Empty
        Friend ReadOnly Property ForumUser() As User
            Get
                Dim uc As New UserController
                Return uc.GetUser(PortalId, ModuleId)
            End Get
        End Property


        Public Overridable ReadOnly Property IsReusable() As Boolean Implements System.Web.IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property


        Public Overridable Sub ProcessRequest(ByVal context As System.Web.HttpContext) Implements System.Web.IHttpHandler.ProcessRequest
            Try
                If Not HttpContext.Current.Items("PortalSettings") Is Nothing Then
                    _ps = CType(HttpContext.Current.Items("PortalSettings"), DotNetNuke.Entities.Portals.PortalSettings)
                    _pid = _ps.PortalId
                Else
                    Dim DomainName As String = Nothing
                    Dim objPortalAliasInfo As DotNetNuke.Entities.Portals.PortalAliasInfo = Nothing
                    Dim sUrl As String = HttpContext.Current.Request.RawUrl.Replace("http://", String.Empty).Replace("https://", String.Empty)
                    objPortalAliasInfo = DotNetNuke.Entities.Portals.PortalSettings.GetPortalAliasInfo(HttpContext.Current.Request.Url.Host)
                    _pid = objPortalAliasInfo.PortalID
                    _ps = DotNetNuke.Entities.Portals.PortalController.GetCurrentPortalSettings()


                End If

                'Dim sc As New Social.SocialSettings
                '_mainSettings = sc.LoadSettings(_ps.PortalId)
                _mainSettings = DataCache.MainSettings(ModuleId)
                '  If context.Request.IsAuthenticated Then
                _isValid = True
                If AdminRequired And Not context.Request.IsAuthenticated Then
                    _isValid = False
                    Exit Sub
                End If
                If AdminRequired And context.Request.IsAuthenticated Then
                    '_isValid = DotNetNuke.Security.PortalSecurity.IsInRole(_ps.AdministratorRoleName)
                    Dim objMC As New DotNetNuke.Entities.Modules.ModuleController
                    Dim objM As DotNetNuke.Entities.Modules.ModuleInfo = objMC.GetModule(ModuleId, TabId)
                    Dim roleIds As String = Permissions.GetRoleIds(objM.AuthorizedEditRoles.Split(CChar(";")), PortalId)
                    _isValid = Modules.ActiveForums.Permissions.HasAccess(roleIds, ForumUser.UserRoles)
                ElseIf AdminRequired And Not context.Request.IsAuthenticated Then
                    _isValid = False
                    Exit Sub
                End If
                Dim p As String = HttpContext.Current.Request.Params("p")
                If Not String.IsNullOrEmpty(p) Then
                    _params = Utilities.JSON.ConvertFromJSONAssoicativeArrayToHashTable(p)
                End If

                If context.Request.Files.Count = 0 Then
                    Dim jsonPost As String = String.Empty
                    Dim prop As String = String.Empty
                    Dim propComplete As Boolean = True
                    Dim val As String = String.Empty
                    Dim tmp As String = String.Empty
                    Dim bObj As Boolean = False
                    'Arrays
                    Dim slist As List(Of String) = Nothing
                    'Dim pairs As NameValueCollection = Nothing
                    Dim pairs As Hashtable = Nothing
                    Dim subPairs As Hashtable = Nothing

                    Dim ht As New Hashtable
                    Dim idx As Integer = 0
                    Dim parentProp As String = String.Empty
                    Dim skip As String = "{}[]:," & Chr(34)
                    Using sr As IO.StreamReader = New IO.StreamReader(context.Request.InputStream, System.Text.Encoding.UTF8)
                        Do Until sr.EndOfStream
                            Dim c As String = ChrW(sr.Read)
                            If idx > 0 And c = CChar("[") Then
                                c = ChrW(sr.Read)
                                bObj = True
                            End If
                            If idx > 0 And c = CChar("{") Then
                                If pairs Is Nothing Then
                                    parentProp = prop
                                    prop = String.Empty
                                    tmp = String.Empty
                                    'pairs = New NameValueCollection
                                    pairs = New Hashtable
                                ElseIf subPairs Is Nothing Then
                                    Dim subString As String = c
                                    Do Until c = CChar("}")
                                        c = ChrW(sr.Read)
                                        subString &= c
                                        If c = CChar("}") Then
                                            Exit Do
                                        End If
                                    Loop
                                    subPairs = Utilities.JSON.ConvertFromJSONAssoicativeArrayToHashTable(subString)
                                    pairs.Add(prop, subPairs)
                                    prop = String.Empty
                                    tmp = String.Empty
                                    subPairs = Nothing
                                    c = ChrW(sr.Read)
                                End If
                            End If

                            If idx > 0 And bObj = True And Not c = "{" Then
                                Dim subItem As String = String.Empty
                                Do Until c = CChar("]")
                                    If slist Is Nothing Then
                                        slist = New List(Of String)
                                    End If
                                    If skip.IndexOf(c) = -1 Then
                                        subItem &= c
                                    End If

                                    c = ChrW(sr.Read)
                                    If c = CChar(",") Or c = CChar("]") Then
                                        slist.Add(subItem)
                                        subItem = String.Empty
                                    End If
                                    If c = CChar("]") Then
                                        c = ChrW(sr.Read)
                                        bObj = False
                                        Exit Do

                                    End If
                                Loop
                            End If
                            If c = CChar(":") Then
                                prop = tmp
                                tmp = String.Empty
                            End If
                            If skip.IndexOf(c) = -1 Then
                                tmp &= c
                            End If
                            If c = CChar(",") Or c = CChar("}") Then
                                If Not String.IsNullOrEmpty(tmp) Then
                                    tmp = HttpUtility.UrlDecode(tmp)
                                End If
                                If Not slist Is Nothing Then
                                    ht.Add(prop, slist)
                                    slist = Nothing
                                ElseIf Not pairs Is Nothing And c = CChar(",") And Not String.IsNullOrEmpty(prop) Then
                                    pairs.Add(prop, tmp)
                                ElseIf Not pairs Is Nothing And c = CChar("}") Then
                                    If Not String.IsNullOrEmpty(tmp) Then
                                        pairs.Add(prop, tmp)
                                    End If
                                    ht.Add(parentProp, pairs)
                                    parentProp = String.Empty
                                    pairs = Nothing
                                ElseIf Not String.IsNullOrEmpty(prop) Then
                                    ht.Add(prop, tmp)
                                End If

                                prop = String.Empty
                                tmp = String.Empty
                            End If

                            idx += 1

                        Loop
                        If Not pairs Is Nothing And Not String.IsNullOrEmpty(parentProp) Then
                            ht.Add(parentProp, pairs)
                        ElseIf Not String.IsNullOrEmpty(prop) And Not String.IsNullOrEmpty(tmp) Then
                            ht.Add(prop, HttpUtility.UrlDecode(tmp))
                        ElseIf Not String.IsNullOrEmpty(prop) And Not slist Is Nothing Then
                            ht.Add(prop, slist)
                        End If

                        'jsonPost = sr.ReadToEnd()
                        sr.Close()
                    End Using
                    _params = ht
                    'End If
                Else
                    Dim ht As New Hashtable
                    For Each s As String In context.Request.Params.AllKeys
                        If Not ht.ContainsKey(s) Then
                            ht.Add(s, context.Request.Params(s))
                        End If

                    Next
                    _params = ht
                End If

                If HttpContext.Current.Request.IsAuthenticated Then
                    UserId = UserController.GetUserIdByUserName(PortalId, HttpContext.Current.User.Identity.Name)
                Else
                    UserId = -1
                End If

            Catch ex As Exception
                _isValid = False
                Exceptions.LogException(ex)

            End Try



        End Sub
        Friend Function BuildOutput(ByVal text As String, ByVal code As OutputCodes, ByVal success As Boolean) As String
            Return BuildOutput(text, code, success, False)
        End Function
        Friend Function BuildOutput(ByVal text As String, ByVal code As OutputCodes, ByVal success As Boolean, ByVal resultisobject As Boolean) As String
            Dim sb As New StringBuilder
            sb.Append("[")
            sb.Append("{")
            sb.Append("""success"":")
            If success Then
                sb.Append("true,")
            Else
                sb.Append("false,")
            End If
            If Not success Then
                Select Case code
                    Case OutputCodes.Exception
                        sb.Append(Utilities.JSON.Pair("error", text))
                    Case OutputCodes.AuthenticationFailed
                        sb.Append(Utilities.JSON.Pair("error", "Authentication Failed"))
                    Case OutputCodes.UnsupportedRequest
                        sb.Append(Utilities.JSON.Pair("error", "Unsupported Request"))
                    Case OutputCodes.UnsupportedRequest
                        sb.Append(Utilities.JSON.Pair("error", "No Results"))
                    Case OutputCodes.AccessDenied
                        sb.Append(Utilities.JSON.Pair("error", "Access Denied"))

                End Select
                sb.Append(",")
            End If
            If String.IsNullOrEmpty(text) Then
                resultisobject = True
                text = "null"
            End If
            sb.Append("""result"":")
            If resultisobject Then
                sb.Append(text)
            Else
                sb.Append("""" & Utilities.JSON.EscapeJsonString(text) & """")
            End If

            sb.Append("}")
            If IsDebug Then
                sb.Append(",{")
                For Each s As String In Params.Keys
                    sb.Append(Utilities.JSON.Pair(s, Params(s).ToString))
                    sb.Append(",")
                Next
                sb.Append(Utilities.JSON.Pair("userid", UserId.ToString))
                sb.Append(",")
                sb.Append(Utilities.JSON.Pair("url", HttpContext.Current.Request.RawUrl.ToString))
                sb.Append("}")
            End If
            sb.Append("]")
            Return sb.ToString
        End Function
    End Class
End Namespace
